function FileUpload(config, file) {
    config = config || {};
    // 大小限制
    this.maxFileSize = config.maxFileSize || 0;
    this.url = config.url;
    this.fieldName = config.fieldName;
    this.params = config.params || {};

    this.file = file;
    this.progressTarget = config.progressTarget;

    return this;
}

FileUpload.prototype = {
    upload: function(success, failed) {
        this.buildHTML();

        if (!this.valid()) {
            return;
        }

        this.success = success;
        this.failed = failed;

        var fd = new FormData();
        fd.append(this.fieldName, this.file);

        for (var k in this.params) {
            if (this.params.hasOwnProperty(k)) {
                fd.append(k, this.params[k]);
            }
        }

        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", this.uploadProgress.bind(this), false);
        xhr.addEventListener("load", this.uploadComplete.bind(this), false);
        xhr.addEventListener("error", this.uploadFailed.bind(this), false);
        // xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", this.url);
        xhr.send(fd);
    },

    valid: function() {
        var size = this.file.size / 1000;
        if(this.maxFileSize && size > this.maxFileSize) {
            this.$el.find('.file-percent').html('文件大小超过限制' + this.maxFileSize + 'KB');
            this.$el.find('.file-del').on('click', function() {
                $(this).remove();
            });
            return false;
        }
        return true;
    },
    buildHTML: function() {
        this.$el = $('<div></div>');
    },
    uploadProgress: function(evt) {
        if (evt.lengthComputable) {
            var percentComplete = Math.round(evt.loaded * 100 / evt.total);
            this.$el.find('.file-percent').html(percentComplete.toString() + '%');
        } else {
            this.$el.find('.file-percent').html('上传失败');
        }
    },
    uploadComplete: function(evt) {
        try {
            // var res = JSON.parse(evt.target.responseText);
            this.$el.find('.file-percent').html('').hide();
        } catch (e) {
            this.$el.find('.file-percent').html('complete, 上传失败');
        }
        this.$el.find('.file-action').show();

        var succ = this.success;
        if(typeof succ === 'function') {
            var res = {};
            try {
                res = JSON.parse(evt.target.responseText);
            }
            catch(e) {
                throw new Error('responseText parse error(success function)');
            }

            if(res.error) {
                typeof this.failed === 'function' && this.failed.call(this, res, evt);
            } else {
                succ.call(this, res, evt);
            }
        }
    },
    uploadFailed: function(evt) {
        this.$el.find('.file-percent').html('failed, 上传失败');

        var failed = this.failed;
        if(typeof failed === 'function') {
            var res = {};
            try {
                res = JSON.parse(evt.target.responseText);
            }
            catch(e) {
                throw new Error('responseText parse error(failed function)');
            }
            failed.call(this, res, evt);
        }
    },
    uploadCanceled: function(evt) {}
};